import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
import mysql from "mysql";
import dayjs from "dayjs";
import { createHash } from "crypto";
//@ts-ignore
import Crypt from "node-jsencrypt";
import { v4 as uuidv4 } from "uuid";

import {
  AuthService,
  CheckTokenRes,
  CheckTokenResData,
  PrivateKey,
  PublicKey,
} from "../common";

import * as grpc from "@grpc/grpc-js";

const cache = new Map();

const connection = mysql.createConnection({
  host: "localhost",
  port: 3306,
  user: "root",
  password: "password",
  database: "mmodb",
});

const crypt = new Crypt();
crypt.setKey(PrivateKey);

const app = express();
app.use(cors());
app.use(bodyParser.json());

app.post("/api/register", (req, res) => {
  console.log(req.body);
  let { account, password } = req.body;
  account = crypt.decrypt(account);
  password = crypt.decrypt(password);

  console.log(account, password);

  const hash = createHash("md5");
  hash.update(password);
  const passHash = hash.digest("hex");

  connection.query(
    "insert into user (account, password, created_time) values (?, ?, ?)",
    [account, passHash, dayjs().format("YYYY-MM-DD HH:mm:mm")],
    function (err, result) {
      if (err) {
        console.log(err);
        return;
      }
      console.log(result);
    }
  );

  res.json({});
});

app.post("/api/login", (req, res) => {
  console.log("login start");
  let { account, password } = req.body;
  account = crypt.decrypt(account);
  password = crypt.decrypt(password);

  console.log(account, password);

  const hash = createHash("md5");
  hash.update(password);
  const passHash = hash.digest("hex");

  connection.query(
    "select * from user where account = ? and password = ?",
    [account, passHash],
    function (err, result, fields) {
      if (err) {
        console.log(err);
        return;
      }
      if (result.length > 0) {
        console.log("login success");
        console.log(result);
        const token = uuidv4();
        cache.set(token, account);

        res.json({ token });
      } else {
        console.log("login failed");
        console.log(result);
      }
    }
  );
});

app.get("/", (req, res) => {
  res.send("hello world");
});

app.listen(3000);

console.log("auth 服务");

const server = new grpc.Server();
server.addService(AuthService, {
  checkToken(call: any, callback: any) {
    const token = call.request.getToken();

    const res = new CheckTokenRes();
    if (cache.has(token)) {
      console.log("token exists");
      const resData = new CheckTokenResData();

      resData.setAccount(cache.get(token));
      res.setData(resData);
    } else {
      res.setError("token not exists");
    }
    callback(null, res);
  },
});

server.bindAsync(
  "localhost:3333",
  grpc.ServerCredentials.createInsecure(),
  () => {
    server.start();
    console.log("rpc server started");
  }
);
